package com.meta.common.utils;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: xieZW
 * @Date: 2021/11/25 19:48
 */
public class WeChatUtils {

    private static final Logger logger = LoggerFactory.getLogger(WeChatUtils.class);

    /**
     * 微信小程序入口
     **/
    private static String WECHAT_JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";

    /**
     * 微信小程序SessionKey
     **/
    public static JSONObject findSessionKey(String appId, String secret, String code) {

        if (appId == null || secret == null || code == null) {
            return new JSONObject();
        }
        String url = WECHAT_JSCODE2SESSION_URL.replace("APPID", appId).replace("SECRET", secret).replace("JSCODE", code);
        logger.info("Wechat Application request sessionkey:" + url);
        JSONObject jsonObject = JSONObject.parseObject(get(url));
        logger.info(String.format("Wechat Application User Login Info: %s", jsonObject.toJSONString()));
        return jsonObject;
    }

    private static final String ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

    public static final String ACCESS_TOKEN = "KEY_ACCESS_TOKEN";

    /**
     * 7200s
     **/
    public static final int ACCESS_TOKEN_EXPIRES = 7000;

    /**
     * 小程序码 accessToken
     **/
    public static String getAccessToken(String appId, String appSecrit) {

        if (appId == null || appSecrit == null) {
            return null;
        }

        String url = ACCESSTOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecrit);
        logger.info("GET XCX ACCESS TOKEN URL 的值：{}", url);
        JSONObject jsonObject = JSONObject.parseObject(get(url));
        String accessToken = jsonObject.getString("access_token");
        logger.info("GET XCX ACCESS TOKEN 的值：{}", accessToken);

        return accessToken;
    }

    /**
     * 小程序码
     **/
    public final static String QRCODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN";
    public final static String QRCODE_URL_2 = "https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN";

    public static String getQrcode(String page, String scene, String width, String accessToken) {

        JSONObject data = new JSONObject();
        data.put("page", page);
        data.put("scene", scene);
        data.put("width", width);
        Map<String, String> headersMap = new HashMap<>();
        headersMap.put("Accept", "Accept");
        String url = QRCODE_URL.replace("ACCESS_TOKEN", accessToken);

        try {
            HttpResponse response = getQrcodeInfo(url, data.toJSONString(), headersMap);
            byte[] reqByte = IOUtils.toByteArray(response.getEntity().getContent());
            return Base64.getEncoder().encodeToString(reqByte);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    private static String DEFAULT_ENCODING = "UTF-8";

    /**
     * 获取消息
     */
    private static String get(String url) {

        String result = "";
        logger.info("POST XCX URL:{}  ", url);
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET");
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            // 连接超时30秒// 读取超时30秒
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
            System.setProperty("sun.net.client.defaultReadTimeout", "30000");
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            return new String(jsonBytes, DEFAULT_ENCODING);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }

    public static String post(String url, String jsonData, Map<String, String> headers) {

        String result = "";
        logger.info("POST XCX URL:{} PARAMS:{} ", url, jsonData);
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            if (headers != null) {
                headers.forEach((key, value) -> {
                    httpPost.setHeader(key, headers.get(value));
                });
            }
            httpPost.setEntity(new BufferedHttpEntity(new StringEntity(jsonData, DEFAULT_ENCODING)));
            CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
            return new String(IOUtils.toByteArray(response.getEntity().getContent()), DEFAULT_ENCODING);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }

    public static HttpResponse getQrcodeInfo(String url, String jsonData, Map<String, String> headers) {

        logger.info("POST XCX URL:{} PARAMS:{} ", url, jsonData);
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            if (headers == null) {
                headers.forEach((key, value) -> {
                    httpPost.setHeader(key, headers.get(value));
                });
            }
            httpPost.setEntity(new BufferedHttpEntity(new StringEntity(jsonData, DEFAULT_ENCODING)));
            return HttpClients.createDefault().execute(httpPost);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    public static BufferedInputStream sendPost(String accessToken, JSONObject json) {

        URL url = null;
        try {
            url = new URL(WeChatUtils.QRCODE_URL_2.replace("ACCESS_TOKEN", accessToken));

            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            // 发送POST请求必须设置如下两行
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
            printWriter.write(json.toString());
            // flush输出流的缓冲
            printWriter.flush();
            //开始获取数据
            BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
            return bis;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
